package graph.outils.io;

import java.awt.geom.Point2D;
import java.io.File;
import java.util.Collection;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import graph.algorithms.maxflow.FlowEdge;
import graph.algorithms.maxflow.FlowNetwork;
import graph.drawings.EdgeDrawing;
import graph.drawings.GraphDrawing;
import graph.drawings.VertexDrawing;

public class GraphInput {
	public GraphDrawing readFromMatrixFile(String filePath) {
		
		return null;
	}
	
	public static FlowNetwork getFlowNetworkFrom(GraphDrawing graphDrawing) {
		FlowNetwork flowNetwork = null;
		
		Collection<VertexDrawing> vertexs = graphDrawing.getVertexs();
		Collection<EdgeDrawing> edges = graphDrawing.getEdges();
		
		int V = vertexs.size() ;
		flowNetwork = new FlowNetwork(V);
		
		for (EdgeDrawing ed : edges) {
            int v = Integer.parseInt(ed.getStartVertex().getKey());
            int w = Integer.parseInt(ed.getEndVertex().getKey());
            int capacity = ed.getValue();
            
            flowNetwork.addEdge(new FlowEdge(v, w, capacity));
        }
		
		return flowNetwork;
	}
	
	public static GraphDrawing UpdateGraphDrawingFrom(FlowNetwork flowNetwork, GraphDrawing graphDrawing) {
		GraphDrawing graph = graphDrawing;
		
		int V = flowNetwork.V();
		
		 VertexDrawing vertex = null;
		 for(int v = 0; v < V; v++) {
			 for (FlowEdge e : flowNetwork.adj(v)) {
					int w = e.other(v);
					
					String edgeKey = String.format("%d>%d", e.from(), w);
					graph.updateValueForEdge(edgeKey, (int)e.capacity());
			 }
		 }
		
		return graph;
	}
	
	
	public static GraphDrawing readXmlFile(String filePath) {
		GraphDrawing graphDrawing = null;

		try {
			graphDrawing = new GraphDrawing();
			
			File fXmlFile = new File(filePath);
			DocumentBuilderFactory dbFactory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
			Document doc = dBuilder.parse(fXmlFile);
			doc.getDocumentElement().normalize();

			NodeList listOfVertexs = doc.getElementsByTagName("Vertex");
			VertexDrawing vertex = null;
			for (int temp = 0; temp < listOfVertexs.getLength(); temp++) {
				Node nNode = listOfVertexs.item(temp);
				if (nNode.getNodeType() == Node.ELEMENT_NODE) {

					Element eElement = (Element) nNode;
					String key = eElement.getAttribute("Key");
					double x = Double.parseDouble(eElement.getAttribute("X"));
					double y = Double.parseDouble(eElement.getAttribute("Y"));
					
					vertex = new VertexDrawing(key, new Point2D.Double(x, y));
					graphDrawing.addShape(vertex);
				}
			}
			
			NodeList listOfEdges = doc.getElementsByTagName("Edge");
			EdgeDrawing	edge = null;
			for (int temp = 0; temp < listOfEdges.getLength(); temp++) {
				Node nNode = listOfEdges.item(temp);
				if (nNode.getNodeType() == Node.ELEMENT_NODE) {

					Element eElement = (Element) nNode;
					int value = Integer.parseInt(eElement.getAttribute("Value"));
					String from = eElement.getAttribute("From");
					String to = eElement.getAttribute("To");
					
					VertexDrawing start = graphDrawing.getVertex(from);
					VertexDrawing end = graphDrawing.getVertex(to);
					EdgeDrawing ed = new EdgeDrawing(start, end );
					ed.setValue(value);
					graphDrawing.addShape(ed);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return graphDrawing;
	}
}
